﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using log4net;
using log4net.Config;
using MoroMoro.Samples.ToDoList.Application;
using MoroMoro.Samples.ToDoList.Application.DataStores;
using MoroMoro.Samples.ToDoList.Presentation.Views;
using MoroMoro.Samples.ToDoList.Presentation.ErrorMessages;

namespace MoroMoro.Samples.ToDoList.Presentation
{
    /// <summary>
    /// アプリケーションの
    /// </summary>
    static class Program
    {
        /// <summary>
        /// log4net ロガーを取得します。
        /// </summary>
        private static readonly ILog _log = LogManager.GetLogger("App");

        /// <summary>
        /// アプリケーションのメイン エントリ ポイントです。
        /// </summary>
        [STAThread]
        static void Main()
        {
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
            XmlConfigurator.Configure();
            try
            {
                _log.Info("アプリケーションが起動しました。");

                bool dataStorePrepred = false;
                var dataStorePreparationScript = new DataStorePreparationScript();
                dataStorePreparationScript.Success += (sender, e) =>
                {
                    dataStorePrepred = true;
                };
                dataStorePreparationScript.Error += (sender, e) =>
                {
                    var errorMessage = new DataStorePreparationErrorMessage();
                    e.Errors.HandledBy(errorMessage);
                    MessageBox.Show(errorMessage, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
                };
                dataStorePreparationScript.Execute();

                if (!dataStorePrepred)
                {
                    return;
                }

                using (var facade = new ToDoListFacade())
                {
                    //System.Windows.Forms.Application.ThreadException += Application_ThreadException;
                    System.Windows.Forms.Application.EnableVisualStyles();
                    System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false);
                    System.Windows.Forms.Application.Run(new ToDoListForm(facade));
                }
            }
            finally
            {
                _log.Info("アプリケーションを終了します。");
            }
        }

        /// <summary>
        /// 現在のアプリケーションドメイン内で発生した未処理の例外を処理します。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            var exception = e.ExceptionObject as Exception;

            if (_log != null)
            {
                MessageBox.Show("致命的なエラーが発生しました。アプリケーションを終了します。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
                _log.Fatal("致命的なエラーが発生しました。", exception);
            }
            else
            {
                string message = string.Format("致命的なエラーが発生しました。アプリケーションを終了します。\nこのエラーは記録できません。\n\n[エラーの内容]\n{0}", exception);
                MessageBox.Show(message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            System.Windows.Forms.Application.Exit();
        }
    }
}
